#include "measure.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
using namespace std;


Measure::Measure()
{
    //较小文件的默认长度
    PROC_MAXBUF = 1024 * 4;
    //每个CPU的 /proc/stat文件长度
    STAT_MAXBUF = 1024 * 64;
    //每一个CPU的/proc/cpuinfo文件长度，最多允许256个CPU
    CPUINFO_MAXBUF = 512 * 256;
    //每一个CPU的/proc/cpuinfo文件为20行
    //PROC_MAXLINES = 20 * 256 * sizeof(char *);
    //
//    errorOn = 0;
//    //
//    errorLength = 100;
//    fp = NULL;
//    fileName = NULL;
//    lines = NULL;
//    //line = NULL;
//    buf = NULL;
//    readInterval = 0;
//    reRead = 0;
}

bool Measure::OpenFile(FILE *fp, char *fileName)
{
    bool flag = false;  //标记文件是否打开正常
    char errBuf[1024];  //存放出错信息
    fp = fopen(fileName,"r");
    if(fp == NULL){
        sprintf(errBuf,"不能打开文件：%s", fileName);
        // 将出错信息存入日志文件
        ErrorLog *pErrorLog = new ErrorLog();
        pErrorLog->log_error(AT,errBuf);
        return false;
    }
    else{
        rewind(fp);
        return true;
    }
}

/*
求disk时， index = 4;
求memory时， index = 3;
*/
void Measure::GetFileResult(const char *fileName, char *pResult, int size, int index){

    int i =0;
    FILE *fp = fopen(fileName, "r");
    if(fp == NULL){
        printf("Can not open file %s\n", fileName);
        exit(1);
    }

    for( ; i < index; i++){
        fgets(pResult, size, fp);
    }
}


void Measure::ExecuteCommand(const char *command, const char *fileName, char *pReslut, int size, int index){

    char cmdStr[100];
    memset(cmdStr, 0, 100);

    strcat(cmdStr, command);
    strcat(cmdStr, ">");
    strcat(cmdStr, fileName);

    printf("%s\n", cmdStr);
    system(cmdStr);

    GetFileResult(fileName, pReslut, size, index);
}

int Measure::CommandPipe(const char *command, char *pResult, int size)
{
    int fd[2];          // 父进程用的pipe描述符
    int pid;
    int count;
    int left;
    char* p = 0;        // 转移存储空间
    int maxlen = size -1;
    memset(pResult, 0, size);

    //create a pipe
    if(pipe(fd))
        //return two file desciption:
        //fd[0] opened for reading;fd[1] opened for writing
    {
        printf("pipe error\n");
        return -1;
    }

    // there is a pipe in the child process
    if((pid = fork()) == 0)
    {
        int fd2[2];
        if(pipe(fd2))
        {
            printf("pipe2 error\n");
            return -1;
        }

        //close(1);       //close file filed descriptor 1
        //dup2 return a new FD named the second parameter,that is 1.if FD 1 has been
        //opened,close it firest.
        dup2(fd2[1],1); //copy STDOUT-TERMINAL
        close(fd[0]);   //close fd[0],read
        close(fd2[1]);  //close fd2[1],write

        //
        system(command);//OUTPUT CONTEXT TO STDOUT  // 这个地方是没有错误的
        //read data from FD fd2[0] to pResult.Transacte context form STDOUT
        read(fd2[0], pResult, maxlen);
        pResult[strlen(pResult)-1] = 0;
        //printf("result is %s\n",pResult);

        write(fd[1], pResult, strlen(pResult));
        close(fd2[0]);

        exit(0);
    }

    // parent process
    close(fd[1]);
    p = pResult;
    //printf("p is %s\n",p);
    left = maxlen;
    while((count = read(fd[0], p, left)))
    {
        p += count;
        left -= count;
        if(left == 0)
            break;
    }

    close(fd[0]);
    return 0;
}

/*
void Measure::proc_read(Measure *meas)
{
    char errBuf[1024];
    int bytes = 0;
    int size = 0;
    int found;
    int i;

    ErrorLog *pErrorLog = new ErrorLog();
    if(meas->readInterval == 1)
        return;
    // 验证文件打开是否正常
    if(meas->fp == 0)
    {
        if((meas->fp = fopen(meas->fileName, "r")) == NULL)
        {
            sprintf(errBuf, "failed to open file %s", meas->fileName);
            pErrorLog->log_error(AT,errBuf);
            meas->fp = 0;
            return;
        }
    }
    rewind(meas->fp);
    //
    if(meas->measureItem == 0)
        bytes = CPUINFO_MAXBUF - 1;
    else if (meas->measureItem == 1)
        bytes = STAT_MAXBUF - 1;
    else
        bytes = PROC_MAXBUF - 1;

    //
    size = fread(meas->buf, 1, bytes, meas->fp);

    meas->buf[size] = 0;// string already
    meas->lines = 0;
    meas->line[0] = &meas->buf[0];
    //
    if(meas->measureItem == 2)
    {
        found = 0;
        for(i = 0; i < size; i++)
        {
            if(found == 0 && meas->buf[i] == ')' && meas->buf[i+1] == ' '
               && meas->buf[i+2] == '(')
            {
                meas->buf[i+1] = '\n';
                found = 1;
            }
            else
            {
                if(meas->buf[i] == ')' && meas->buf[i+1] == ' '
                   && meas->buf[i+2] == '#')
                    meas->buf[i+1];
                if(meas->buf[i] == '#' && meas->buf[i+2] == '1')
                    meas->buf[i] = '\n';
            }
        }
    }

    // other condition
    for(i = 0; i < size; i++)
    {
        // replace Tab into space
        if(meas->buf[i] == '\t')
            meas->buf[i] = ' ';
        // replace new line with null
        else if(meas->buf[i] == '\n')
        {
            meas->lines++; // new line
            meas->buf[i] = '\0';
            meas->line[meas->lines] = &meas->buf[i + 1];
        }
        // 超过制定行数就截断
        if(meas->lines == PROC_MAXLINES - 1)
            break;
    }

    //
    if(reRead)
    {
        fclose(meas->fp);
        meas->fp = 0;
    }
    meas->readInterval = 1;
}
*/
